Notes: This document summarizes only the key outputs of the final multiple imputation process for SPHC-B 2014. More detailed R scripts are available in the R Notebook “SPHC-B-2014.Rmd”.


1. Load Packages

library(naniar)
library(dplyr)
library(jomo)
library(mitml)
library(ggplot2)

2. SPHC-B 2014

2.1. Incomplete dataset

load("/Volumes/LGBT Project data/Multiple Imputation/d_2014_incomplete.RData")
summary( d_2014_incomplete )
 sampling_strata_region calibrated_weight no.of.population        sexual_identity_2014 sexual_identity_fluidity
 Lidingö : 1061         Min.   :  8.497   Min.   :  7463   Heterosexual     :18104     0   :12228              
 Nacka   : 1058         1st Qu.: 40.581   1st Qu.: 29879   Homosexual       :  245     1   :  864              
 Botkyrka:  790         Median : 66.588   Median : 44852   Bisexual         :  397     NA's: 9158              
 Täby    :  651         Mean   : 79.311   Mean   : 46291   None of the above: 1503                             
 Danderyd:  623         3rd Qu.:103.465   3rd Qu.: 62422   NA's             : 2001                             
 Bromma  :  610         Max.   :450.081   Max.   :108458                                                       
 (Other) :17457                                                                                                
      age            sex              country_of_birth       education         income                 marital_status 
 Min.   :16.00   Male  : 9867   Sweden        :18178   <=9 years  : 3237   Min.   :     0   Never married    : 7327  
 1st Qu.:37.00   Female:12383   Europe        : 2282   10-12 years: 8036   1st Qu.:  2191   Currently married:10872  
 Median :51.00                  Outside Europe: 1790   >=13 years :10818   Median :  3093   Other            : 4051  
 Mean   :51.18                                         NA's       :  159   Mean   :  3800                            
 3rd Qu.:66.00                                                             3rd Qu.:  4259                            
 Max.   :99.00                                                             Max.   :204536                            
                 "print"                                            NA's   :42                                
 living_alone personal_support weight_strata  
 yes : 4272   yes :18030       15     :  911  
 no  :16318   no  : 2405       7      :  910  
 NA's: 1660   NA's: 1815       19     :  904  
                               4      :  902  
                               22     :  901  
                               9      :  899  
                               (Other):16823  
sapply( d_2014_incomplete, class ) # all continuous variables are numeric, and all categorical variables are factor
  sampling_strata_region        calibrated_weight         no.of.population     sexual_identity_2014 
                "factor"                "numeric"                "numeric"                 "factor" 
sexual_identity_fluidity                      age                      sex         country_of_birth 
                "factor"                "numeric"                 "factor"                 "factor" 
               education                   income           marital_status             living_alone 
                "factor"                "numeric"                 "factor"                 "factor" 
        personal_support            weight_strata 
                "factor"                 "factor" 
miss_var_summary( d_2014_incomplete ) # 41.2% missing in sexual_identity_fluidity, 9.0% in sexual_identity_2014, 8.2% in personal_support, 7.5% in living_alone, 0.7% in education, and 0.2% in income

2.2. Two-level multivariate normal imputation

# specify imputation model
# fml_imp_2014 <- sexual_identity_fluidity + sexual_identity_2014 + personal_support + living_alone + education + income ~ 1 + age*sex + country_of_birth + marital_status + ( 1 | weight_strata )

# final imputation with the chosen number of iterations
# imp_final_2014 <- jomoImpute( data = d_2014_incomplete,
#                               formula = fml_imp_2014,
#                               random.L1 = "full",
#                               n.burn = 5000,
#                               n.iter = 2000,
#                               m = 60,
#                               seed = 12345
#                               ) # took around 23 hours

load("/Volumes/LGBT Project data/Multiple Imputation/imp_final_2014.RData")
summary( imp_final_2014 )

Call:

jomoImpute(data = d_2014_incomplete, formula = fml_imp_2014, 
    random.L1 = "full", n.burn = 5000, n.iter = 2000, m = 60, 
    seed = 12345)

Cluster variable:         weight_strata 
Target variables:         sexual_identity_fluidity sexual_identity_2014 personal_support living_alone education income 
Fixed effect predictors:  (Intercept) age sex country_of_birth marital_status age:sex 
Random effect predictors: (Intercept) 

Performed 5000 burn-in iterations, and generated 60 imputed data sets,
each 2000 iterations apart. 

Potential scale reduction (Rhat, imputation phase):
 
          Min    25%   Mean Median    75%    Max
Beta:   1.000  1.002  1.028  1.007  1.019  1.334
Psi:    1.000  1.000  1.008  1.003  1.010  1.057
Sigma:  1.000  1.000  1.839  1.133  1.695 24.201

Largest potential scale reduction:
Beta: [2,2], Psi: [8,2], Sigma: [52,2]

Missing data per variable:
    weight_strata sexual_identity_fluidity sexual_identity_2014 personal_support living_alone education income
MD% 0             41.2                     9.0                  8.2              7.5          0.7       0.2   
    sampling_strata_region calibrated_weight no.of.population age sex country_of_birth marital_status
MD% 0                      0                 0                0   0   0                0             
plot( imp_final_2014, trace = "all", print = "beta" )

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

2.3. Validate imputed data

# extract imputed datasets
original_data_2014 <- mitmlComplete( imp_final_2014, print = 0 ) # extract original incomplete dataset
implist_2014 <- mitmlComplete( imp_final_2014, print = "all" ) # extract all imputed datasets

original_data_2014$imputation <- "0"
all_data_2014 <- bind_rows( original_data_2014, 
                            bind_rows( implist_2014, .id = "imputation" ) ) # merge datasets
all_data_2014$imputation <- as.numeric( all_data_2014$imputation )
summary( all_data_2014 )
 weight_strata     sexual_identity_fluidity        sexual_identity_2014 personal_support living_alone  
 15     :  55571   0   :1234374             Heterosexual     :1205793   yes :1192975     yes : 282997  
 7      :  55510   1   : 113718             Homosexual       :  18107   no  : 162460     no  :1072593  
 19     :  55144   NA's:   9158             Bisexual         :  28311   NA's:   1815     NA's:   1660  
 4      :  55022                            None of the above: 103038                                  
 22     :  54961                            NA's             :   2001                                  
 9      :  54839                                                                                       
 (Other):1026203                                                                                       
       education          income       sampling_strata_region calibrated_weight no.of.population      age       
 <=9 years  :199571   Min.   :-49053   Lidingö :  64721       Min.   :  8.497   Min.   :  7463   Min.   :16.00  
 10-12 years:493886   1st Qu.:  2190   Nacka   :  64538       1st Qu.: 40.581   1st Qu.: 29879   1st Qu.:37.00  
 >=13 years :663634   Median :  3093   Botkyrka:  48190       Median : 66.588   Median : 44852   Median :51.00  
 NA's       :   159   Mean   :  3799   Täby    :  39711       Mean   : 79.311   Mean   : 46291   Mean   :51.18  
                      3rd Qu.:  4263   Danderyd:  38003       3rd Qu.:103.469   3rd Qu.: 62422   3rd Qu.:66.00  
                      Max.   :204536   Bromma  :  37210       Max.   :450.081   Max.   :108458   Max.   :99.00  
                      NA's   :42       (Other) :1064877                                                         
     sex               country_of_birth             marital_status     imputation
 Male  :601887   Sweden        :1108858   Never married    :446947   Min.   : 0  
 Female:755363   Europe        : 139202   Currently married:663192   1st Qu.:15  
                 Outside Europe: 109190   Other            :247111   Median :30  
                                                                     Mean   :30  
                                                                     3rd Qu.:45  
                                                                     Max.   :60  
                                                                                 
# sexual identity in 2014
ggplot( all_data_2014[ !is.na( all_data_2014$sexual_identity_2014 ), ],
        aes( fill = sexual_identity_2014, x = imputation ) ) + 
  geom_bar( position = "fill" ) + 
  scale_y_continuous( labels = scales::percent ) + 
  scale_fill_discrete( name = "Sexual identity in 2014" ) +
  labs(
    x = "Imputation number",
    y = "Proportion",
    caption = "Notes: Imputation number 0 represents the original incomplete dataset." ) +
  theme_classic() +
  theme( axis.title.x = element_text( family = "Arial", size = 11 ),
         axis.text.x = element_text( family = "Arial", size = 11 ),
         axis.text.y = element_text( family = "Arial", size = 11 ),
         axis.title.y = element_text( family = "Arial", size = 11 ),
         legend.text = element_text( family = "Arial", size = 10 ),
         legend.title = element_text( family = "Arial", size = 10 ),
         legend.position = "bottom",
         plot.caption = element_text( family = "Arial", size = 10, hjust = 0 ) 
  )


# change in sexual identity during 2014-2021
ggplot( all_data_2014[ !is.na( all_data_2014$sexual_identity_fluidity ), ],
        aes( fill = sexual_identity_fluidity, x = imputation ) ) + 
  geom_bar( position = "fill" ) + 
  scale_y_continuous( labels = scales::percent ) + 
  scale_fill_discrete( name = "Change in sexual identity during 2014-2021", labels = c( "No", "Yes" ) ) +
  labs(
    x = "Imputation number",
    y = "Proportion",
    caption = "Notes: Imputation number 0 represents the original incomplete dataset." ) +
  theme_classic() +
  theme( axis.title.x = element_text( family = "Arial", size = 11 ),
         axis.text.x = element_text( family = "Arial", size = 11 ),
         axis.text.y = element_text( family = "Arial", size = 11 ),
         axis.title.y = element_text( family = "Arial", size = 11 ),
         legend.text = element_text( family = "Arial", size = 10 ),
         legend.title = element_text( family = "Arial", size = 10 ),
         legend.position = "bottom",
         plot.caption = element_text( family = "Arial", size = 10, hjust = 0 ) 
  )


# education
ggplot( all_data_2014[ !is.na( all_data_2014$education ), ],
        aes( fill = education, x = imputation ) ) + 
  geom_bar( position = "fill" ) + 
  scale_y_continuous( labels = scales::percent ) + 
  scale_fill_discrete( name = "Level of education" ) +
  labs(
    x = "Imputation number",
    y = "Proportion",
    caption = "Notes: Imputation number 0 represents the original incomplete dataset." ) +
  theme_classic() +
  theme( axis.title.x = element_text( family = "Arial", size = 11 ),
         axis.text.x = element_text( family = "Arial", size = 11 ),
         axis.text.y = element_text( family = "Arial", size = 11 ),
         axis.title.y = element_text( family = "Arial", size = 11 ),
         legend.text = element_text( family = "Arial", size = 10 ),
         legend.title = element_text( family = "Arial", size = 10 ),
         legend.position = "bottom",
         plot.caption = element_text( family = "Arial", size = 10, hjust = 0 ) 
  )


# income
summary( all_data_2014$income )
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
 -49053    2190    3093    3799    4263  204536      42 
nrow( all_data_2014[ all_data_2014$income < 0 & !is.na( all_data_2014$income ), ] ) #  564 imputed values are negative
[1] 564
# living status
ggplot( all_data_2014[ !is.na( all_data_2014$living_alone ), ],
        aes( fill = living_alone, x = imputation ) ) + 
  geom_bar( position = "fill" ) + 
  scale_y_continuous( labels = scales::percent ) + 
  scale_fill_discrete( name = "Living alone", labels = c( "Yes", "No" ) ) +
  labs(
    x = "Imputation number",
    y = "Proportion",
    caption = "Notes: Imputation number 0 represents the original incomplete dataset." ) +
  theme_classic() +
  theme( axis.title.x = element_text( family = "Arial", size = 11 ),
         axis.text.x = element_text( family = "Arial", size = 11 ),
         axis.text.y = element_text( family = "Arial", size = 11 ),
         axis.title.y = element_text( family = "Arial", size = 11 ),
         legend.text = element_text( family = "Arial", size = 10 ),
         legend.title = element_text( family = "Arial", size = 10 ),
         legend.position = "bottom",
         plot.caption = element_text( family = "Arial", size = 10, hjust = 0 ) 
  )


# personal support
ggplot( all_data_2014[ !is.na( all_data_2014$personal_support ), ],
        aes( fill = personal_support, x = imputation ) ) + 
  geom_bar( position = "fill" ) + 
  scale_y_continuous( labels = scales::percent ) + 
  scale_fill_discrete( name = "Personal support", labels = c( "Yes", "No" ) ) +
  labs(
    x = "Imputation number",
    y = "Proportion",
    caption = "Notes: Imputation number 0 represents the original incomplete dataset." ) +
  theme_classic() +
  theme( axis.title.x = element_text( family = "Arial", size = 11 ),
         axis.text.x = element_text( family = "Arial", size = 11 ),
         axis.text.y = element_text( family = "Arial", size = 11 ),
         axis.title.y = element_text( family = "Arial", size = 11 ),
         legend.text = element_text( family = "Arial", size = 10 ),
         legend.title = element_text( family = "Arial", size = 10 ),
         legend.position = "bottom",
         plot.caption = element_text( family = "Arial", size = 10, hjust = 0 ) 
  )

LS0tCnRpdGxlOiAiVmFsaWRhdGlvbiBvZiBNdWx0aXBsZSBJbXB1dGF0aW9uIGluIFNQSEMtQiAyMDE0IgphdXRob3I6IFdpbGxpIFpoYW5nICh3aWxsaS56aGFuZ0BraS5zZSksIE1hdHRlbyBRdWFydGFnbm8Kb3V0cHV0OiBodG1sX25vdGVib29rCmVkaXRvcl9vcHRpb25zOgogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgo8YnI+CgojIyMjIyAqTm90ZXM6KiBUaGlzIGRvY3VtZW50IHN1bW1hcml6ZXMgb25seSB0aGUga2V5IG91dHB1dHMgb2YgdGhlIGZpbmFsIG11bHRpcGxlIGltcHV0YXRpb24gcHJvY2VzcyBmb3IgU1BIQy1CIDIwMTQuIE1vcmUgZGV0YWlsZWQgUiBzY3JpcHRzIGFyZSBhdmFpbGFibGUgaW4gdGhlIFIgTm90ZWJvb2sgWyJTUEhDLUItMjAxNC5SbWQiXShodHRwczovL2dpdGh1Yi5jb20vd2lsbGl6aGFuZy9UZW1wb3JhbC1UcmVuZHMtaW4tU2V4dWFsLUlkZW50aXR5LWFuZC1Tb2Npb2RlbW9ncmFwaGljLURpc3Bhcml0aWVzLWluLVN0b2NraG9sbS1Db3VudHktMjAxMC10by0yMDIxL2Jsb2IvbWFpbi9TUEhDLUItMjAxNC5SbWQpLgoKPGJyPgoKIyMjIDEuIExvYWQgUGFja2FnZXMKYGBge3IgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KG5hbmlhcikKbGlicmFyeShkcGx5cikKbGlicmFyeShqb21vKQpsaWJyYXJ5KG1pdG1sKQpsaWJyYXJ5KGdncGxvdDIpCmBgYAoKIyMjIDIuIFNQSEMtQiAyMDE0CiMjIyMgMi4xLiBJbmNvbXBsZXRlIGRhdGFzZXQKYGBge3J9CmxvYWQoIi9Wb2x1bWVzL0xHQlQgUHJvamVjdCBkYXRhL011bHRpcGxlIEltcHV0YXRpb24vZF8yMDE0X2luY29tcGxldGUuUkRhdGEiKQpzdW1tYXJ5KCBkXzIwMTRfaW5jb21wbGV0ZSApCnNhcHBseSggZF8yMDE0X2luY29tcGxldGUsIGNsYXNzICkgIyBhbGwgY29udGludW91cyB2YXJpYWJsZXMgYXJlIG51bWVyaWMsIGFuZCBhbGwgY2F0ZWdvcmljYWwgdmFyaWFibGVzIGFyZSBmYWN0b3IKbWlzc192YXJfc3VtbWFyeSggZF8yMDE0X2luY29tcGxldGUgKSAjIDQxLjIlIG1pc3NpbmcgaW4gc2V4dWFsX2lkZW50aXR5X2ZsdWlkaXR5LCA5LjAlIGluIHNleHVhbF9pZGVudGl0eV8yMDE0LCA4LjIlIGluIHBlcnNvbmFsX3N1cHBvcnQsIDcuNSUgaW4gbGl2aW5nX2Fsb25lLCAwLjclIGluIGVkdWNhdGlvbiwgYW5kIDAuMiUgaW4gaW5jb21lCmBgYAoKIyMjIyAyLjIuIFR3by1sZXZlbCBtdWx0aXZhcmlhdGUgbm9ybWFsIGltcHV0YXRpb24KYGBge3J9CiMgc3BlY2lmeSBpbXB1dGF0aW9uIG1vZGVsCiMgZm1sX2ltcF8yMDE0IDwtIHNleHVhbF9pZGVudGl0eV9mbHVpZGl0eSArIHNleHVhbF9pZGVudGl0eV8yMDE0ICsgcGVyc29uYWxfc3VwcG9ydCArIGxpdmluZ19hbG9uZSArIGVkdWNhdGlvbiArIGluY29tZSB+IDEgKyBhZ2Uqc2V4ICsgY291bnRyeV9vZl9iaXJ0aCArIG1hcml0YWxfc3RhdHVzICsgKCAxIHwgd2VpZ2h0X3N0cmF0YSApCgojIGZpbmFsIGltcHV0YXRpb24gd2l0aCB0aGUgY2hvc2VuIG51bWJlciBvZiBpdGVyYXRpb25zCiMgaW1wX2ZpbmFsXzIwMTQgPC0gam9tb0ltcHV0ZSggZGF0YSA9IGRfMjAxNF9pbmNvbXBsZXRlLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm11bGEgPSBmbWxfaW1wXzIwMTQsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tLkwxID0gImZ1bGwiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4uYnVybiA9IDUwMDAsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbi5pdGVyID0gMjAwMCwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtID0gNjAsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZCA9IDEyMzQ1CiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAjIHRvb2sgYXJvdW5kIDIzIGhvdXJzCgpsb2FkKCIvVm9sdW1lcy9MR0JUIFByb2plY3QgZGF0YS9NdWx0aXBsZSBJbXB1dGF0aW9uL2ltcF9maW5hbF8yMDE0LlJEYXRhIikKc3VtbWFyeSggaW1wX2ZpbmFsXzIwMTQgKQpwbG90KCBpbXBfZmluYWxfMjAxNCwgdHJhY2UgPSAiYWxsIiwgcHJpbnQgPSAiYmV0YSIgKQpgYGAKCiMjIyMgMi4zLiBWYWxpZGF0ZSBpbXB1dGVkIGRhdGEKYGBge3J9CiMgZXh0cmFjdCBpbXB1dGVkIGRhdGFzZXRzCm9yaWdpbmFsX2RhdGFfMjAxNCA8LSBtaXRtbENvbXBsZXRlKCBpbXBfZmluYWxfMjAxNCwgcHJpbnQgPSAwICkgIyBleHRyYWN0IG9yaWdpbmFsIGluY29tcGxldGUgZGF0YXNldAppbXBsaXN0XzIwMTQgPC0gbWl0bWxDb21wbGV0ZSggaW1wX2ZpbmFsXzIwMTQsIHByaW50ID0gImFsbCIgKSAjIGV4dHJhY3QgYWxsIGltcHV0ZWQgZGF0YXNldHMKCm9yaWdpbmFsX2RhdGFfMjAxNCRpbXB1dGF0aW9uIDwtICIwIgphbGxfZGF0YV8yMDE0IDwtIGJpbmRfcm93cyggb3JpZ2luYWxfZGF0YV8yMDE0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRfcm93cyggaW1wbGlzdF8yMDE0LCAuaWQgPSAiaW1wdXRhdGlvbiIgKSApICMgbWVyZ2UgZGF0YXNldHMKYWxsX2RhdGFfMjAxNCRpbXB1dGF0aW9uIDwtIGFzLm51bWVyaWMoIGFsbF9kYXRhXzIwMTQkaW1wdXRhdGlvbiApCnN1bW1hcnkoIGFsbF9kYXRhXzIwMTQgKQoKIyBzZXh1YWwgaWRlbnRpdHkgaW4gMjAxNApnZ3Bsb3QoIGFsbF9kYXRhXzIwMTRbICFpcy5uYSggYWxsX2RhdGFfMjAxNCRzZXh1YWxfaWRlbnRpdHlfMjAxNCApLCBdLAogICAgICAgIGFlcyggZmlsbCA9IHNleHVhbF9pZGVudGl0eV8yMDE0LCB4ID0gaW1wdXRhdGlvbiApICkgKyAKICBnZW9tX2JhciggcG9zaXRpb24gPSAiZmlsbCIgKSArIAogIHNjYWxlX3lfY29udGludW91cyggbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50ICkgKyAKICBzY2FsZV9maWxsX2Rpc2NyZXRlKCBuYW1lID0gIlNleHVhbCBpZGVudGl0eSBpbiAyMDE0IiApICsKICBsYWJzKAogICAgeCA9ICJJbXB1dGF0aW9uIG51bWJlciIsCiAgICB5ID0gIlByb3BvcnRpb24iLAogICAgY2FwdGlvbiA9ICJOb3RlczogSW1wdXRhdGlvbiBudW1iZXIgMCByZXByZXNlbnRzIHRoZSBvcmlnaW5hbCBpbmNvbXBsZXRlIGRhdGFzZXQuIiApICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMSApLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggZmFtaWx5ID0gIkFyaWFsIiwgc2l6ZSA9IDExICksCiAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTEgKSwKICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTEgKSwKICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMCApLAogICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMCApLAogICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTAsIGhqdXN0ID0gMCApIAogICkKCiMgY2hhbmdlIGluIHNleHVhbCBpZGVudGl0eSBkdXJpbmcgMjAxNC0yMDIxCmdncGxvdCggYWxsX2RhdGFfMjAxNFsgIWlzLm5hKCBhbGxfZGF0YV8yMDE0JHNleHVhbF9pZGVudGl0eV9mbHVpZGl0eSApLCBdLAogICAgICAgIGFlcyggZmlsbCA9IHNleHVhbF9pZGVudGl0eV9mbHVpZGl0eSwgeCA9IGltcHV0YXRpb24gKSApICsgCiAgZ2VvbV9iYXIoIHBvc2l0aW9uID0gImZpbGwiICkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCApICsgCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSggbmFtZSA9ICJDaGFuZ2UgaW4gc2V4dWFsIGlkZW50aXR5IGR1cmluZyAyMDE0LTIwMjEiLCBsYWJlbHMgPSBjKCAiTm8iLCAiWWVzIiApICkgKwogIGxhYnMoCiAgICB4ID0gIkltcHV0YXRpb24gbnVtYmVyIiwKICAgIHkgPSAiUHJvcG9ydGlvbiIsCiAgICBjYXB0aW9uID0gIk5vdGVzOiBJbXB1dGF0aW9uIG51bWJlciAwIHJlcHJlc2VudHMgdGhlIG9yaWdpbmFsIGluY29tcGxldGUgZGF0YXNldC4iICkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dCggZmFtaWx5ID0gIkFyaWFsIiwgc2l6ZSA9IDExICksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTEgKSwKICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMSApLAogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMSApLAogICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dCggZmFtaWx5ID0gIkFyaWFsIiwgc2l6ZSA9IDEwICksCiAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dCggZmFtaWx5ID0gIkFyaWFsIiwgc2l6ZSA9IDEwICksCiAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMCwgaGp1c3QgPSAwICkgCiAgKQoKIyBlZHVjYXRpb24KZ2dwbG90KCBhbGxfZGF0YV8yMDE0WyAhaXMubmEoIGFsbF9kYXRhXzIwMTQkZWR1Y2F0aW9uICksIF0sCiAgICAgICAgYWVzKCBmaWxsID0gZWR1Y2F0aW9uLCB4ID0gaW1wdXRhdGlvbiApICkgKyAKICBnZW9tX2JhciggcG9zaXRpb24gPSAiZmlsbCIgKSArIAogIHNjYWxlX3lfY29udGludW91cyggbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50ICkgKyAKICBzY2FsZV9maWxsX2Rpc2NyZXRlKCBuYW1lID0gIkxldmVsIG9mIGVkdWNhdGlvbiIgKSArCiAgbGFicygKICAgIHggPSAiSW1wdXRhdGlvbiBudW1iZXIiLAogICAgeSA9ICJQcm9wb3J0aW9uIiwKICAgIGNhcHRpb24gPSAiTm90ZXM6IEltcHV0YXRpb24gbnVtYmVyIDAgcmVwcmVzZW50cyB0aGUgb3JpZ2luYWwgaW5jb21wbGV0ZSBkYXRhc2V0LiIgKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTEgKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMSApLAogICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCggZmFtaWx5ID0gIkFyaWFsIiwgc2l6ZSA9IDExICksCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dCggZmFtaWx5ID0gIkFyaWFsIiwgc2l6ZSA9IDExICksCiAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTAgKSwKICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTAgKSwKICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dCggZmFtaWx5ID0gIkFyaWFsIiwgc2l6ZSA9IDEwLCBoanVzdCA9IDAgKSAKICApCgojIGluY29tZQpzdW1tYXJ5KCBhbGxfZGF0YV8yMDE0JGluY29tZSApCm5yb3coIGFsbF9kYXRhXzIwMTRbIGFsbF9kYXRhXzIwMTQkaW5jb21lIDwgMCAmICFpcy5uYSggYWxsX2RhdGFfMjAxNCRpbmNvbWUgKSwgXSApICMgIDU2NCBpbXB1dGVkIHZhbHVlcyBhcmUgbmVnYXRpdmUKCiMgbGl2aW5nIHN0YXR1cwpnZ3Bsb3QoIGFsbF9kYXRhXzIwMTRbICFpcy5uYSggYWxsX2RhdGFfMjAxNCRsaXZpbmdfYWxvbmUgKSwgXSwKICAgICAgICBhZXMoIGZpbGwgPSBsaXZpbmdfYWxvbmUsIHggPSBpbXB1dGF0aW9uICkgKSArIAogIGdlb21fYmFyKCBwb3NpdGlvbiA9ICJmaWxsIiApICsgCiAgc2NhbGVfeV9jb250aW51b3VzKCBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQgKSArIAogIHNjYWxlX2ZpbGxfZGlzY3JldGUoIG5hbWUgPSAiTGl2aW5nIGFsb25lIiwgbGFiZWxzID0gYyggIlllcyIsICJObyIgKSApICsKICBsYWJzKAogICAgeCA9ICJJbXB1dGF0aW9uIG51bWJlciIsCiAgICB5ID0gIlByb3BvcnRpb24iLAogICAgY2FwdGlvbiA9ICJOb3RlczogSW1wdXRhdGlvbiBudW1iZXIgMCByZXByZXNlbnRzIHRoZSBvcmlnaW5hbCBpbmNvbXBsZXRlIGRhdGFzZXQuIiApICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMSApLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggZmFtaWx5ID0gIkFyaWFsIiwgc2l6ZSA9IDExICksCiAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTEgKSwKICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTEgKSwKICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMCApLAogICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMCApLAogICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTAsIGhqdXN0ID0gMCApIAogICkKCiMgcGVyc29uYWwgc3VwcG9ydApnZ3Bsb3QoIGFsbF9kYXRhXzIwMTRbICFpcy5uYSggYWxsX2RhdGFfMjAxNCRwZXJzb25hbF9zdXBwb3J0ICksIF0sCiAgICAgICAgYWVzKCBmaWxsID0gcGVyc29uYWxfc3VwcG9ydCwgeCA9IGltcHV0YXRpb24gKSApICsgCiAgZ2VvbV9iYXIoIHBvc2l0aW9uID0gImZpbGwiICkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCApICsgCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSggbmFtZSA9ICJQZXJzb25hbCBzdXBwb3J0IiwgbGFiZWxzID0gYyggIlllcyIsICJObyIgKSApICsKICBsYWJzKAogICAgeCA9ICJJbXB1dGF0aW9uIG51bWJlciIsCiAgICB5ID0gIlByb3BvcnRpb24iLAogICAgY2FwdGlvbiA9ICJOb3RlczogSW1wdXRhdGlvbiBudW1iZXIgMCByZXByZXNlbnRzIHRoZSBvcmlnaW5hbCBpbmNvbXBsZXRlIGRhdGFzZXQuIiApICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMSApLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggZmFtaWx5ID0gIkFyaWFsIiwgc2l6ZSA9IDExICksCiAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTEgKSwKICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTEgKSwKICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMCApLAogICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoIGZhbWlseSA9ICJBcmlhbCIsIHNpemUgPSAxMCApLAogICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KCBmYW1pbHkgPSAiQXJpYWwiLCBzaXplID0gMTAsIGhqdXN0ID0gMCApIAogICkKYGBg